/**
 * Project Name:demo
 * File Name:OverflowController.java
 * Package Name:com.cloud.demo.overflow
 * Date:2016年3月8日下午3:46:30
 * Copyright (c) 2016, LiHao All Rights Reserved.
 *
*/

package com.cloud.demo.overflow;

import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * ClassName:OverflowController <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason:	 TODO ADD REASON. <br/>
 * Date:     2016年3月8日 下午3:46:30 <br/>
 * @author   LiHao
 * @version  
 * @since    JDK 1.6
 * @see 	 
 */
public class OverflowController1 {
	private static Logger logger = LoggerFactory.getLogger(OverflowController1.class);
	// 每秒并发访问控制数量  
    final static int MAX_QPS = 50;  
    // 并发控制信号量  
    final static Semaphore semaphore = new Semaphore(MAX_QPS);  
    // 监控每秒并发访问次数（理论上accessCount.get() <= MAX_QPS）  
    final static AtomicInteger accessCount = new AtomicInteger(0);  
  
    // 模拟远程访问  
    private static void remoteCall(int i, int j) {  
//        System.out.println(String.format("%s - %s: %d %d", new Date(), Thread.currentThread(), i, j));  
    	logger.info(String.format("%s - %s: %d %d", new Date(), Thread.currentThread(), i, j));
    }  
  
    private static void releaseWork() { // 每秒release一次  
        // release semaphore thread  
        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {  
            @Override  
            public void run() {  
            	int count=accessCount.get();
            	logger.debug("releaseWork"+count);
            	accessCount.set(0);  
                semaphore.release(count); //信号量加上用了多少
                
            }  
        }, 1000, 1000, TimeUnit.MILLISECONDS);  
    }  
  
    // 模拟并发访问控制  
    private static void simulateAccess(final int m, final int n)  
            throws Exception { // m : 线程数；n : 调用数  
        ExecutorService pool = Executors.newFixedThreadPool(100);  
        for (int i = m; i > 0; i--) {  
            final int x = i;  
            pool.submit(new Runnable() {  
                @Override  
                public void run() {  
                    for (int j = n; j > 0; j--) { 
//                    	logger.debug("j"+j);
                        try {  
                            Thread.sleep(5);  
                        } catch (InterruptedException e) {  
                            e.printStackTrace();  
                        }  
                       
                        semaphore.acquireUninterruptibly(1);  //获取许可 许可减1
                        accessCount.incrementAndGet();  //加1
//                        semaphore.acquire(1);
//                        int a=accessCount.incrementAndGet();
//                        int a=accessCount.getAndIncrement();
//                        logger.info("acquireUninterruptibly"+a);
                        remoteCall(x, j);  
                    }  
                }  
            });  
        }  
  
        pool.shutdown();  
        pool.awaitTermination(1, TimeUnit.HOURS);  
        logger.info("完成");
    }  
  
    public static void main(String[] args) throws Exception {  
        // 开启releaseWork  
        releaseWork();  
          
        // 开始模拟lots of concurrent calls: 100 * 1000  
        simulateAccess(100, 200);  
    }  

}

